package com.odontosis.view.servicoconveniado;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.hibernate.Session;

import com.odontosis.acesso.filtro.PermissaoAcesso;
import com.odontosis.dao.ParametrosDAO;
import com.odontosis.dto.DadosFiodDto;
import com.odontosis.entidade.Convenio;
import com.odontosis.entidade.Paciente;
import com.odontosis.entidade.ParametrosFIOD;
import com.odontosis.entidade.Procedimento;
import com.odontosis.entidade.ServicoConveniado;
import com.odontosis.entidade.Usuario;
import com.odontosis.ioc.ContainerIoc;
import com.odontosis.service.PacienteService;
import com.odontosis.service.ParametrosService;
import com.odontosis.service.ProcedimentoService;
import com.odontosis.service.ServicoConveniadoService;
import com.odontosis.util.StringUtilsOdontosis;
import com.odontosis.view.OdontosisAction;

public class AcaoServicoConvenio extends OdontosisAction<ServicoConveniadoService> {

	@Override
	public ActionForward execute(ActionMapping mapping, ActionForm actionForm,
			HttpServletRequest request, HttpServletResponse response) throws Exception {
		FormServicoConvenio form = (FormServicoConvenio) actionForm;
		if(!StringUtilsOdontosis.isVazia(form.getMetodo())){
			if(form.getMetodo().equals("add")){
			    return onAdicionar(mapping, actionForm, request, response);	
			}else if(form.getMetodo().equals("salvar")){
				return onSalvar(mapping, actionForm, request, response);
			}else if(form.getMetodo().equals("remover")){
				return onRemover(mapping, actionForm, request, response);
			}
		}
		return onIniciar(mapping, form, request, response);
	}
	
	public ActionForward onIniciar(ActionMapping mapping, ActionForm actionForm,
			HttpServletRequest request, HttpServletResponse response) throws Exception {
		FormServicoConvenio form = (FormServicoConvenio) actionForm;
		
		Set<Procedimento> procedimentos = new HashSet<Procedimento>();
		if(!StringUtilsOdontosis.isVazia(form.getAlteracao())){
			ServicoConveniado servicoConvenio = service.load(Long.parseLong(form.getAlteracao()));
			SimpleDateFormat formato = new SimpleDateFormat("dd/MM/yyyy");
			form.setData(formato.format(servicoConvenio.getData()));
			form.setFiod(servicoConvenio.getFiod());
			form.setParcela(servicoConvenio.getParcela().toString());
			form.setPaciente(servicoConvenio.getPaciente().getId().toString());
			form.setPacienteNome(servicoConvenio.getPaciente().getNome());
			form.setDataPericia(servicoConvenio.getDataPericia() !=null ? formato.format(servicoConvenio.getDataPericia()): null);
			form.setGuiaAssinada(servicoConvenio.isGuiaAssinada());
			
			procedimentos.addAll(servicoConvenio.getListaProcedimentos());
			
		}
		request.getSession().setAttribute("proc", procedimentos);
		form.setListaVazia(procedimentos.isEmpty());
		request.setAttribute("colecaoProcedimentos", (Set<Procedimento>) request.getSession().getAttribute("proc"));
		return mapping.getInputForward();
	}
	
	public ActionForward onAdicionar(ActionMapping mapping, ActionForm actionForm,
			HttpServletRequest request, HttpServletResponse response) throws Exception {
		FormServicoConvenio form = (FormServicoConvenio) actionForm;
		
		long id = Long.parseLong(form.getProcedimento());
		Set<Procedimento> procedimentos = new HashSet<Procedimento>();
		if(request.getSession().getAttribute("proc") == null){
			request.getSession().setAttribute("proc", procedimentos);
		}else{
			procedimentos = (Set<Procedimento>) request.getSession().getAttribute("proc");
		}
		
		procedimentos.add(ContainerIoc.getProcedimentoService().load(id));
		form.setListaVazia(procedimentos.isEmpty());
		request.setAttribute("colecaoProcedimentos", procedimentos);
		
		return mapping.getInputForward();
	}
	
	public ActionForward onRemover(ActionMapping mapping, ActionForm actionForm,
			HttpServletRequest request, HttpServletResponse response) throws Exception {
		FormServicoConvenio form = (FormServicoConvenio) actionForm;
		Set<Procedimento> procedimentos = (Set<Procedimento>) request.getSession().getAttribute("proc");
		Set<Procedimento> procedimentosAux = new HashSet<Procedimento>(procedimentos);
		for(Procedimento procedimento:procedimentosAux){
			if(procedimento.getId().intValue() == Integer.parseInt(form.getIdProcedimento())){
				procedimentos.remove(procedimento);
			}
		}
		form.setListaVazia(procedimentos.isEmpty());
		request.setAttribute("colecaoProcedimentos", procedimentos);
		return mapping.getInputForward();
	}
	
	
	public ActionForward onSalvar(ActionMapping mapping, ActionForm actionForm,
			HttpServletRequest request, HttpServletResponse response) throws Exception {
		FormServicoConvenio form = (FormServicoConvenio) actionForm;
		ServicoConveniado servicoConvenio = new ServicoConveniado();
		Usuario usuarioLogado = PermissaoAcesso.getUsuarioLogado(request);
		if(!StringUtilsOdontosis.isVazia(form.getAlteracao())){ //edição do registro
			servicoConvenio = service.load(Long.parseLong(form.getAlteracao()));
			servicoConvenio.setUsuarioUltimaAlteracao(usuarioLogado);
			servicoConvenio.setDataHoraAlteracao(new Date());
		} else {
			servicoConvenio.setUsuario(usuarioLogado);
			servicoConvenio.setDataHoraCadastro(new Date());
			servicoConvenio.setUsuarioUltimaAlteracao(usuarioLogado);
			servicoConvenio.setDataHoraAlteracao(new Date());
		}
		Set<Procedimento> procedimentos = (Set<Procedimento>) request.getSession().getAttribute("proc");
		PacienteService pacienteService = ContainerIoc.getPacienteService();
		Paciente pacienteServico = pacienteService.load(Long.parseLong(form.getPaciente()));
		servicoConvenio.setConvenio(Convenio.POLICIA_MILITAR);
		if(servicoConvenio.getParcela() == null) {
			servicoConvenio.setParcela(service.proximaParcela(pacienteServico,procedimentos));
		}
		
		if(servicoConvenio.getParcela() != null && servicoConvenio.getParcela() >= 25) {
			request.setAttribute("mensagens", "O paciente informado já possui 24 parcelas para o tratamento ortodôntico informado! Por favor insira outro procedimento.");
			return mapping.getInputForward();
		}
		
		servicoConvenio.setFiod(form.getFiod());
		servicoConvenio.setPaciente(pacienteServico);
		servicoConvenio.setAtivo(true);
		servicoConvenio.setGuiaAssinada(form.isGuiaAssinada());
		SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
		servicoConvenio.setData(sdf.parse(form.getData()));
		Date dataPericia = StringUtilsOdontosis.isVazia(form.getDataPericia()) ? null :  sdf.parse(form.getDataPericia());
		servicoConvenio.setDataPericia(dataPericia);
		
		double valor = 0.0;
		
		for(Procedimento procedimento : procedimentos){
			valor += procedimento.getValor().doubleValue();
		}
		servicoConvenio.setValor(valor);
		if(servicoConvenio.getListaProcedimentos() == null){
			servicoConvenio.setListaProcedimentos(new HashSet<Procedimento>());
		}
		servicoConvenio.getListaProcedimentos().clear();
		servicoConvenio.getListaProcedimentos().addAll(procedimentos);

		ProcedimentoService procedimentoService = ContainerIoc.getProcedimentoService();
		for(Procedimento procedimento : procedimentos) {
			procedimentoService.evict(procedimento);
		}

		servicoConvenio.setListaProcedimentos((Set<Procedimento>) request.getSession().getAttribute("proc"));
		for(Procedimento procedimento : servicoConvenio.getListaProcedimentos()) {
			procedimentoService.refresh(procedimento);
		}
		
		boolean imprimir = servicoConvenio.getId() == null;
		if(servicoConvenio.getId() != null) {
			Session session = service.getSession();
			session.evict(session.load(ServicoConveniado.class, servicoConvenio.getId()));
		}
		
		service.saveOrUpdate(servicoConvenio);
		
		return imprimirFiod(mapping, request, servicoConvenio, imprimir);
	}

	public static ActionForward imprimirFiod(ActionMapping mapping, HttpServletRequest request, ServicoConveniado servicoConvenio, boolean imprimir) {
		ParametrosService parametrosService = ContainerIoc.getParametrosService();
		ParametrosFIOD parametrosFIOD = parametrosService.buscarParametrosFiod();
		
		DadosFiodDto dadosFiodDto = new DadosFiodDto();
		dadosFiodDto.setCartaoPaciente(servicoConvenio.getPaciente().getIpsm());
		if(parametrosFIOD.getPessoaFisica() != null && parametrosFIOD.getPessoaFisica().equals(1)) {
			dadosFiodDto.setCpfCredenciado(parametrosService.buscarCpf());
			dadosFiodDto.setNomeCredenciado(parametrosService.buscarDentista());	
		} else {
			dadosFiodDto.setCpfCredenciado(parametrosService.buscarCnpj());
			dadosFiodDto.setNomeCredenciado(parametrosService.buscarClinica());
		}
		dadosFiodDto.setCpfSolicitante(parametrosService.buscarCpf());
		dadosFiodDto.setCroSolicitante(parametrosService.buscarCRO());
		dadosFiodDto.setDataSolicitacao(StringUtilsOdontosis.DateToString(servicoConvenio.getData()));
		dadosFiodDto.setMatriculaPaciente(!StringUtilsOdontosis.isVazia(servicoConvenio.getPaciente().getMatricula()) ? servicoConvenio.getPaciente().getMatricula() : "");
		dadosFiodDto.setNomePaciente(servicoConvenio.getPaciente().getNome());
		dadosFiodDto.setNomeSolicitante(parametrosService.buscarDentista());
		List<Procedimento> procs = new ArrayList<Procedimento>(); 
		procs.addAll(servicoConvenio.getListaProcedimentos());
		String parcelaTratamento = " "+ (servicoConvenio.getParcela() != null && !servicoConvenio.getParcela().equals(0) ? servicoConvenio.getParcela().toString() + " ": "");
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(servicoConvenio.getData());
		int mes = calendar.get(Calendar.MONTH) + 1;
		int ano = calendar.get(Calendar.YEAR); 
		parcelaTratamento += mes + "/" + ano;
		//parcelaTratamento = "";
		dadosFiodDto.setTratamento1((procs.size() >= 1 ? procs.get(0).getNome()+ parcelaTratamento: "") );
		dadosFiodDto.setTratamento2((procs.size() >= 2 ? procs.get(1).getNome()+ parcelaTratamento: "") );
		dadosFiodDto.setTratamento3((procs.size() >= 3 ? procs.get(2).getNome()+ parcelaTratamento: "") );
		dadosFiodDto.setTratamento4((procs.size() >= 4 ? procs.get(3).getNome()+ parcelaTratamento: "") );
		dadosFiodDto.setTratamento5((procs.size() >= 5 ? procs.get(4).getNome()+ parcelaTratamento: "") );
		dadosFiodDto.setTratamento6((procs.size() >= 6 ? procs.get(5).getNome()+ parcelaTratamento: "") );
		dadosFiodDto.setTratamento7((procs.size() >= 7 ? procs.get(6).getNome()+ parcelaTratamento: "") );
		dadosFiodDto.setTratamento8((procs.size() >= 8 ? procs.get(7).getNome()+ parcelaTratamento: "") );
		dadosFiodDto.setTratamento9((procs.size() >= 9 ? procs.get(8).getNome()+ parcelaTratamento: "") );
		dadosFiodDto.setTratamento10((procs.size() >= 10 ? procs.get(9).getNome()+ parcelaTratamento: ""));
		dadosFiodDto.setUf("MG");
		dadosFiodDto.setValor1(procs.size() >= 1 ? StringUtilsOdontosis.formatarDouble(procs.get(0).getValor()): "");
		dadosFiodDto.setValor2(procs.size() >= 2 ? StringUtilsOdontosis.formatarDouble(procs.get(1).getValor()): "");
		dadosFiodDto.setValor3(procs.size() >= 3 ? StringUtilsOdontosis.formatarDouble(procs.get(2).getValor()): "");
		dadosFiodDto.setValor4(procs.size() >= 4 ? StringUtilsOdontosis.formatarDouble(procs.get(3).getValor()): "");
		dadosFiodDto.setValor5(procs.size() >= 5 ? StringUtilsOdontosis.formatarDouble(procs.get(4).getValor()): "");
		dadosFiodDto.setValor6(procs.size() >= 6 ? StringUtilsOdontosis.formatarDouble(procs.get(5).getValor()): "");
		dadosFiodDto.setValor7(procs.size() >= 7 ? StringUtilsOdontosis.formatarDouble(procs.get(6).getValor()): "");
		dadosFiodDto.setValor8(procs.size() >= 8 ? StringUtilsOdontosis.formatarDouble(procs.get(7).getValor()): "");
		dadosFiodDto.setValor9(procs.size() >= 9 ? StringUtilsOdontosis.formatarDouble(procs.get(8).getValor()): "");
		dadosFiodDto.setValor10(procs.size() >= 10 ? StringUtilsOdontosis.formatarDouble(procs.get(9).getValor()): "");
		dadosFiodDto.setValorTotal(StringUtilsOdontosis.formatarDouble(servicoConvenio.getValor()));
		
		request.setAttribute("dadosfiod", dadosFiodDto);
		if(servicoConvenio.getParcela() != null && servicoConvenio.getParcela().intValue() == 24) {
			Collection<String> alerta = new ArrayList<String>();
			alerta.add("24ª Prestação gerada é necessário enviar relatório para autorizar o procedimento.");
			request.setAttribute("alerta", alerta);
			dadosFiodDto.setMensagem("24ª Prestação gerada é necessário enviar relatório para autorizar o procedimento.");
		}
		
		if(imprimir) {
			return mapping.findForward("impressaofiod");
		} else {
			request.setAttribute("sucesso", "Registro atualizado com sucesso.");
			return mapping.findForward("lista");
		}
	}
	
	
	
}
